package com.huajin.codetest.lock;

import java.util.Vector;

/**
 * 锁消除（同步省略）
 * 锁粗化
 * 嵌套锁
 * 
 * 锁消除是发生在编译器级别的一种锁优化方式
 * 
 * 锁消除是Java虚拟机在JIT编译时，通过对运行上下文的扫描，去除不可能存在共享资源竞争的锁，通过锁消除，可以节省毫无意义的请求锁时间
 * 
 * JVM使用JIT（及时编译器）去优化，基于逃逸分析，如果局部变量在运行过程中没有出现逃逸，则可以对其进行优化。
 * 
 * jvm通过锁消除机制，极大的提升了代码运行的效率。也反向证明，即使是偏向锁，轻量级锁，还是会造成很大的性能损耗。
 * 
 * -server：server模式会比client模式作更多的优化
 * -XX:+DoEscapeAnalysis 开启逃逸分析
 * -XX:+EliminateLocks 开启锁粗化和锁消除
 * -Xcomp 
 * -XX:-BackgroundCompilation 
 * -XX:BiasedLockingStartupDelay=0：运行启动偏向锁，更优化
 * 
 */
public class EliminateLocksTest {
	
	/**
	 * StringBuffer类的对象引用sb只会在getString方法使用，不可能被其它线程引用（因为是局部变量，栈私有），
	 * 因此sb是不可能共享的资源，JVM会自动消除StringBuffer对象内部的锁
	 */
	public static String getString(String s1, String s2) {
		//-- StringBuffer线程安全-XX:BiasedLockingStartupDelay=0运行启动偏向锁，更优化
        StringBuffer sb = new StringBuffer();
        //-- append方法使用synchronized修饰，且使用@HotSpotIntrinsicCandidate注解
        sb.append(s1);
        sb.append(s2);
        return sb.toString();
    }
 
    public static void main(String[] args) {
        long tsStart = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            getString("TestLockEliminate ", "Suffix");
        }
        System.out.println("一共耗费：" + (System.currentTimeMillis() - tsStart) + " ms");
        //-- 默认  145
        //-- -XX:+DoEscapeAnalysis 154
        //- -XX:+DoEscapeAnalysis -XX:-EliminateLocks 108
        //-- -XX:+DoEscapeAnalysis -XX:+EliminateLocks 99
    }
    
    public void vectorTest() {
    	Vector<Integer> vector = new Vector<>();
    	for (int i =0; i <10; i++) {
    		vector.add(i);
    	} 
    	System.out.println(vector);
    }
    
    public void test() {
        Object object = new Object();
        synchronized (object) {
            System.out.println("----");
        }
    }
    
    static int i = 0;
    
    public void test1() throws Exception {
        i++;
    }

    public void test2() throws Exception {
        synchronized (new Object()) {
            i++;
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

}
